<?php
class zRSS
{
    var $content;
    var $source;
    var $script_dir;
    var $cfg;
    var $socket;
    function zRSS()
    {
        $this->script_dir=dirname(__FILE__);
    }
    
    /**
     * Получает $this->source из URL
     *
     * @param string $url
     * @return boolean
     */
    function getFromUrl($url)
    {
        if (!class_exists('zSockets'))
        {
            if (!file_exists($this->script_dir."/socket.php"))
            {
                $this->error("Can't load Sockets class",E_USER_ERROR);
                return false;
            }
            require_once($this->script_dir."/socket.php");
        }
        $this->socket=new zSocket($url);
        $this->source=$this->socket->getText();
        if (!$this->source)
        {
            $this->error("Can't get RSS '".$url,E_USER_NOTICE);
            return false;
        }
        $this->parse();
        return true;
    }
    
    /**
     * Разбирает $source и делает $this->content
     *
     * @param string $source
     * @return boolean
     */
    function parse( $source=NULL )
    {
        if ( !$source ) $source=$this->source;
        if ( preg_match("/^.*?<\?xml.+?encoding=\"(.+?)\"\?>.*?<rss.*?version=\"(.*?)\".*?>(.*?)<\/rss>.*$/is",$source,$res) )
        {
            $this->content=new RSS_container();
            $this->content->encoding=$res[1];
            $this->content->version=(int)$res[2];
            if ($this->content->version!=2)
            {
                $this->error("Don't know this version RSS",E_USER_ERROR);
                return false;
            }
            $tmp=trim($res[3]);
            
            if (preg_match("/UTF-8|utf8/i",$this->content->encoding))
            {
                $tmp=$this->convertToWindows($tmp);
            }
            
    
            if ( preg_match_all("/<item>(.+?)<\/item>/is",$tmp,$items) )
            {
                $items=$items[1];
                foreach ((array)$items as $k=>$v)
                {
                    if ( preg_match("/<title.*?>(.+?)<\/title>/is",$v,$tmp_title) AND
                         preg_match("/<link.*?>(.+?)<\/link>/is",$v,$tmp_link) AND
                         preg_match("/<description.*?>(.+?)<\/description>/is",$v,$tmp_description) AND
                         preg_match("/<guid.*?>(.+?)<\/guid>/is",$v,$tmp_guid)
                    )
                    {
                        $tmp_pubDate[1]=strftime("%Y-%m-%d %H:%M:%S");
                        $this->content->addItem($tmp_title[1],$tmp_link[1],$tmp_pubDate[1],$tmp_description[1],$tmp_guid[1]);
                    }
                }
            }
            else 
            {
                $this->error("Can't parse RSS",E_USER_NOTICE);
                return false;
            }
            $tmp=preg_replace("/<item>.*?<\/item>/is","",$tmp);
            if  (   preg_match("/^.*?<title>(.+?)<\/title>/is",$tmp,$tmp1) and
                    preg_match("/^.*?<link>(.+?)<\/link>/is",$tmp,$tmp2) and
                    ( 
                        preg_match("/^.*?<lastBuildDate>(.+?)<\/lastBuildDate>/is",$tmp,$tmp3) or 
                        preg_match("/^.*?<pubDate>(.+?)<\/pubDate>/is",$tmp,$tmp3)
                    )
            )
            {
                preg_match("/^.*?<image>(.+?)<\/image>/is",$tmp,$tmp4);
                if (isset($tmp4[1]))
                {
                    if ( preg_match("/<link>(.+?)<\/link>/is",$tmp4[1],$tmp_image) ) $this->content->image['link']=$tmp_image[1];
                    if ( preg_match("/<url>(.+?)<\/url>/is",$tmp4[1],$tmp_image) ) $this->content->image['url']=$tmp_image[1];
                    if ( preg_match("/<title>(.+?)<\/title>/is",$tmp4[1],$tmp_image) ) $this->content->image['title']=$tmp_image[1];
                }
                preg_match("/^.*?<description>(.+?)<\/description>/is",$tmp,$tmp8);
                $this->content->title=$tmp1[1];
                $this->content->link=$tmp2[1];
                $this->content->lastBuildDate=strtotime($tmp3[1]);
                $this->content->description=(isset($tmp8[1]))?$tmp8[1]:'';
            }
        }
        else
        {
            $this->error("Can't parse RSS",E_USER_NOTICE);
            return false;
        }
        return true;
    }
    
    
    function convertToWindows($str)
    {
        $str=$this->win2utf($str,false);
        return $str;
    }
    function cache($file_name)
    {
        if ( $f=fopen($file_name,"w") )
        {
            fwrite($f,serialize($this->content));
            fclose($f);
        }
        else 
        {
            $this->error("Can't save RSS",E_USER_NOTICE);
        }
    }
    function loadFromCache($file_name)
    {
        $tmp=file_get_contents($file_name);
        $this->content=unserialize($tmp);
    }
    function dump()
    {
        print "<pre>".var_export($this->content,true)."</pre><hr/>";
    }
    function error($message,$level)
    {
        $tmp=debug_backtrace();
        $msg="<div style='font-size:11px;font-family:Verdana;color:#990000;font-weight:bold;'>".$message."<br/>in ".$tmp[0]['file']."(".$tmp[0]['line'].")</div>";
        print $msg;
        //trigger_error($message,$level);
        //$this->log($message);
    }
    function win2utf($string,$direction=true)
    {
        $win2utf=array('А'=>chr(208).chr(144),'Б'=>chr(208).chr(145),'В'=>chr(208).chr(146),'Г'=>chr(208).chr(147),'Д'=>chr(208).chr(148),'Е'=>chr(208).chr(149),'Ё'=>chr(208).chr(129),'Ж'=>chr(208).chr(150),'З'=>chr(208).chr(151),'И'=>chr(208).chr(152),'Й'=>chr(208).chr(153),'К'=>chr(208).chr(154),'Л'=>chr(208).chr(155),'М'=>chr(208).chr(156),'Н'=>chr(208).chr(157),'О'=>chr(208).chr(158),'П'=>chr(208).chr(159),'Р'=>chr(208).chr(160),'С'=>chr(208).chr(161),'Т'=>chr(208).chr(162),'У'=>chr(208).chr(163),'Ф'=>chr(208).chr(164),'Х'=>chr(208).chr(165),'Ц'=>chr(208).chr(166),'Ч'=>chr(208).chr(167),'Ш'=>chr(208).chr(168),'Щ'=>chr(208).chr(169),'Ъ'=>chr(208).chr(170),'Ы'=>chr(208).chr(171),'Ь'=>chr(208).chr(172),'Э'=>chr(208).chr(173),'Ю'=>chr(208).chr(174),'Я'=>chr(208).chr(175),'а'=>chr(208).chr(176),'б'=>chr(208).chr(177),'в'=>chr(208).chr(178),'г'=>chr(208).chr(179),'д'=>chr(208).chr(180),'е'=>chr(208).chr(181),'ё'=>chr(209).chr(145),'ж'=>chr(208).chr(182),'з'=>chr(208).chr(183),'и'=>chr(208).chr(184),'й'=>chr(208).chr(185),'к'=>chr(208).chr(186),'л'=>chr(208).chr(187),'м'=>chr(208).chr(188),'н'=>chr(208).chr(189),'о'=>chr(208).chr(190),'п'=>chr(208).chr(191),'р'=>chr(209).chr(128),'с'=>chr(209).chr(129),'т'=>chr(209).chr(130),'у'=>chr(209).chr(131),'ф'=>chr(209).chr(132),'х'=>chr(209).chr(133),'ц'=>chr(209).chr(134),'ч'=>chr(209).chr(135),'ш'=>chr(209).chr(136),'щ'=>chr(209).chr(137),'ъ'=>chr(209).chr(138),'ы'=>chr(209).chr(139),'ь'=>chr(209).chr(140),'э'=>chr(209).chr(141),'ю'=>chr(209).chr(142),'я'=>chr(209).chr(143),chr(150)=>'-',chr(45)=>'-');
        if (!$direction) $win2utf=array_flip($win2utf);
        $string=strtr($string,$win2utf);
        return $string;
    }
}
/**
 * Класс контейнер для RSS
 *
 */
class RSS_container
{
    var $encoding;
    var $version;
    var $title;
    var $link;
    var $description;
    var $image;
    var $lastBuildDate;
    var $items;
    function RSS_container()
    {
        $this->items=array();
        $this->image=array('link'=>'','url'=>'','title'=>'');
    }
    function addItem($title,$link,$pubDate,$description,$guid)
    {
        $tmp=new RSS_item();
        $tmp->set($title,$pubDate,$description,$link,$guid);
        $this->items[$tmp->getGuID()]=$tmp;
    }
}
/**
 * Один ITEM из RSS
 *
 */
class RSS_item
{
    
	/**
     * заголовок
     *
     * @var string
     */
    var $title;

    /**
     * Дата публикации
     *
     * @var int
     */
    var $pubDate;

    /**
     * Текст новости
     *
     * @var string
     */
    var $description;

    /**
     * Ссылка на новость
     *
     * @var string
     */
    var $link;

    /**
     * Guid of RSS-item
     *
     * @var md5 от оригинального guID (32 символа)
     */
    var $guid;

    
    function setTitle($title)
    {
        $this->title=$title;
    }
    
    function setPubDate($pubDate)
    {
        $pubDate=strtotime($pubDate);
        $this->pubDate=$pubDate;
    }
    
    function setDescription($description)
    {
        $description=html_entity_decode($description);
        $description=preg_replace("/<\/table>/i","\n",$description);
        $description=preg_replace("/<br.*?>/i","\n",$description);
        $description=preg_replace("/<p>/i","\n",$description);
        $description=preg_replace("/\n+/i","\n",$description);
        $description=preg_replace("/&nbsp;/i"," ",$description);
        $description=strip_tags($description,'<a>');
        $description=trim($description);
        $this->description=$description;
    }
    function setLink($link)
    {
        $this->link=$link;
    }
    function setGuID($guID)
    {
        $guID=md5($guID);
        $this->guid=$guID;
    }
    function set($title,$pubDate,$descrption,$link,$guid)
    {
        $this->setTitle($title);
        $this->setDescription($descrption);
        $this->setPubDate($pubDate);
        $this->setLink($link);
        $this->setGuID($guid);
    }
    
    
    function GetTitle()
    {
        return $this->title;
    }
    
    
    function GetPubDate()
    {
        return $this->pubDate;
    }
    
    
    function GetDescription()
    {
        return $this->description;
    }
    
    
    function GetLink()
    {
        return $this->link;
    }
    
    
    function GetGuID()
    {
        return $this->guid;
    }
}
?>